﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Windows;
using System.Windows.Threading;
using Microsoft.Phone.Controls;
using PhoneNetTools.Ntp;

namespace Sample.Ntp
{
    public partial class MainPage : PhoneApplicationPage
    {
        // a timer to update the displayed time every second
        private DispatcherTimer _timer = new DispatcherTimer();

        // this is the SNTP client
        private SntpClient _client = new SntpClient();

        // the local clock offset, set once the time is retrieved from a time server
        private TimeSpan? _offset;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            // create and start the timer
            _timer.Interval = TimeSpan.FromSeconds(1.0);
            _timer.Tick += Timer_Tick;
            _timer.Start();

            // hook the completed event of the SNTP client
            _client.Completed += Client_Completed;
        }

        private void Client_Completed(object sender, SntpResultEventArgs e)
        {
            // the events of the SNTP client are raised on a background thread
            // => use something like this to marshal execution back to the UI thread
            //    if you need to access UI elements
            // => OR implement proper locking or similar if you don't need to access 
            //    the UI, but access shared resources
            if (!CheckAccess())
            {
                Dispatcher.BeginInvoke(() => Client_Completed(sender, e));
            }
            else
            {
                // first check for errors
                if (e.Error != SocketError.Success)
                {
                    MessageBox.Show("Error while fetching time from server: " + e.Error);
                    return;
                }

                // if there was no error, we have an offset here
                _offset = e.Message.LocalClockOffset;
                ResponseText.Text = e.Message.ToString();
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // update the time display
            var now = DateTime.Now;
            LocalTimeText.Text = now.ToString("u");

            // if we have an offset, display the corrected time also
            if (_offset != null)
            {
                CorrectedTimeText.Text = (now + _offset.Value).ToString("u");
            }
        }

        private void FetchTimeButton_Click(object sender, RoutedEventArgs e)
        {
            var timeServer = TimeServerTextBox.Text;
            if (string.IsNullOrEmpty(timeServer))
            {
                MessageBox.Show("Please enter a time server IP address or host name, for example 'ptbtime1.ptb.de'.");
                return;
            }

            // create the endpoint and invoke the SNTP client's GetTimeAsync convenience method.
            // you can also use one of the other overloads that takes only the host name or IP address,
            // or even the generic methods that allow sending a NTP message you've built and set up yourself
            var endPoint = new DnsEndPoint(timeServer, Constants.NtpPort);
            _client.GetTimeAsync(endPoint);
        }
    }
}